package ru.bragnikita.test.https;

/**
 * @author Nikita.Brazhnikov
 */

import javax.net.ssl.*;
import javax.xml.ws.BindingProvider;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.MalformedURLException;
import java.net.URL;
import java.security.SecureRandom;
import java.security.cert.Certificate;
import java.security.cert.X509Certificate;
import java.util.ArrayList;
import java.util.List;

class RabbitCounterClient {
	private static final String url_s = "https://localhost:9876/fib";

	public static void main(String[] args) {
		new RabbitCounterClient().do_it();
	}

	private void do_it() {
		try {
// Create a context that doesn't check certificates.
			SSLContext ssl_ctx = SSLContext.getInstance("TLS");
			TrustManager[] trust_mgr = get_trust_mgr();
			ssl_ctx.init(null, // key manager
			             trust_mgr, // trust manager
			             new SecureRandom()); // random number generator
			HttpsURLConnection.setDefaultSSLSocketFactory(ssl_ctx.getSocketFactory());
			URL url = new URL(url_s);
			HttpsURLConnection conn = (HttpsURLConnection) url.openConnection();
// Guard against "bad hostname" errors during handshake.
			conn.setHostnameVerifier(new HostnameVerifier() {
				public boolean verify(String host, SSLSession sess) {
					if (host.equals("localhost")) return true;
					else return false;
				}
			});
// Test request
			List<Integer> nums = new ArrayList<Integer>();
			nums.add(3);
			nums.add(5);
			nums.add(7);
			conn.setDoInput(true);
			conn.setDoOutput(true);
			conn.setRequestMethod("POST");
			conn.addRequestProperty(BindingProvider.USERNAME_PROPERTY, "nikita");
			conn.addRequestProperty(BindingProvider.PASSWORD_PROPERTY, "pass");
			conn.connect();
			OutputStream out = conn.getOutputStream();
			out.write(nums.toString().getBytes("UTF-8"));
			byte[] buffer = new byte[4096];
			InputStream in = conn.getInputStream();
			in.read(buffer);
			System.out.println(new String(buffer));
			dump_features(conn);
			conn.disconnect();
		} catch (MalformedURLException e) {
			System.err.println(e);
		} catch (IOException e) {
			e.printStackTrace();
		} catch (Exception e) {
			System.err.println(e);
		}
	}

	private TrustManager[] get_trust_mgr() {
		TrustManager[] certs = new TrustManager[]{
			 new X509TrustManager() {
				 public X509Certificate[] getAcceptedIssuers() {
					 return null;
				 }

				 public void checkClientTrusted(X509Certificate[] certs, String t) {
				 }

				 public void checkServerTrusted(X509Certificate[] certs, String t) {
				 }
			 }
		};
		return certs;
	}

	private void dump_features(HttpsURLConnection conn) {
		try {
			print("Status code: " + conn.getResponseCode());
			print("Cipher suite: " + conn.getCipherSuite());
			Certificate[] certs = conn.getServerCertificates();
			for (Certificate cert : certs) {
				print("\tCert. type: " + cert.getType());
				print("\tHash code: " + cert.hashCode());
				print("\tAlgorithm: " + cert.getPublicKey().getAlgorithm());
				print("\tFormat: " + cert.getPublicKey().getFormat());
				print("");
			}
		} catch (Exception e) {
			System.err.println(e);
		}
	}

	private void print(String s) {
		System.out.println(s);
	}
}